#!/bin/bash
#
# Creates a release tarball directly from git

# Note that the tarball contents might not exactly match
# a particular git commit, particularly for untagged
# commits.
#
# An alternative approach would be to generate source tarballs
# using CPack. That would remove our dependency on git, but if
# Autotools is any indication it would require continuous
# maintenance.
#
# Copyright 2011 Balint Reczey <balint@balintreczey.hu>
#
# Wireshark - Network traffic analyzer
# By Gerald Combs <gerald@wireshark.org>
# Copyright 1998 Gerald Combs
#
# SPDX-License-Identifier: GPL-2.0-or-later

set -e -u -o pipefail

DESTDIR=.

while getopts "d:" OPTCHAR ; do
    case $OPTCHAR in
        d) DESTDIR=$OPTARG ;;
        *) printf "Unknown option %s\n" "$OPTCHAR" ;;
    esac
done
shift $(( OPTIND - 1 ))

# The remaining parameter, if set, is a package version such as 3.4.5
# or 3.4.5-67-gabcd4321
# By default the version from make-version.py + CMake is used.
PROJECT_VERSION=@PROJECT_VERSION@
if test -n "${1-}"; then
    PROJECT_VERSION="$1"
fi

TARBALL="${DESTDIR}/wireshark-${PROJECT_VERSION}.tar.xz"

# A tarball produced by 'git archive' will have the $Format string
# substituted due to the use of 'export-subst' in .gitattributes.
# shellcheck disable=SC2016
COMMIT='$Format:%H$'

if [[ $COMMIT != \$F* ]] ; then
    # This file was extracted from a tarball produced by git archive
    # and so we are not in a git repository.
    if [[ -f "$TARBALL" ]] ; then
        # git get-tar-commit-id works outside a git repo, as it
        # only reads the first 1024 bytes of the tar extended header.
        if [[ $(git get-tar-commit-id < <(xzcat "$TARBALL")) == "$COMMIT" ]] ; then
            echo "$TARBALL commit ID matches $COMMIT."
        else
            # Allow people to make changes to a downloaded source tarball
            # and re-tar it?
            echo "WARNING: $TARBALL is not the original git archive."
        fi
        exit 0
    fi

    echo ""
    echo "The build system cannot produce a source tarball outside of a git repository."
    echo "If you are trying to build an RPM package from source extracted from a tarball,"
    echo "copy it (i.e., wireshark-${PROJECT_VERSION}.tar.xz) to"
    echo "$DESTDIR"
    echo "and run the build command again."

    exit 1
fi

STASH_ID=$(git stash create || echo "")

if [[ -n "$STASH_ID" ]] ; then
    echo "Setting commit from stash $STASH_ID"
    COMMIT="$STASH_ID"
else
    echo "Setting commit from HEAD"
    COMMIT="HEAD"
fi

if [ -f "$TARBALL" ] ; then
    printf "Found %s\\n" "$TARBALL"
    if TARBALL_ID=$(git get-tar-commit-id < <(xzcat "$TARBALL")) && COMMIT_ID=$(git rev-parse --verify "$COMMIT") ; then
        if [[ $TARBALL_ID == "$COMMIT_ID" ]] ; then
            echo "$TARBALL commit ID matches $COMMIT."
            exit 0
        fi
    fi
fi

echo "Creating $TARBALL from $COMMIT"

XZ_OPTS=
echo . | xz --threads=0 > /dev/null 2>&1 && XZ_OPTS=--threads=0

git archive --prefix="wireshark-${PROJECT_VERSION}/" "$COMMIT" | xz $XZ_OPTS > "$TARBALL"
